<?php

declare(ENCODING = 'UTF-8');

/*                                                                        *
 * This script is part of the TYPO3 project - inspiring people to share!  *
 *                                                                        *
 * TYPO3 is free software; you can redistribute it and/or modify it under *
 * the terms of the GNU General Public License version 2 as published by  *
 * the Free Software Foundation.                                          *
 *                                                                        *
 * This script is distributed in the hope that it will be useful, but     *
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN-    *	
 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General      *
 * Public License for more details.                                       *
 *                                                                        */	

/**
 * @package auxo
 * @subpackage tests
 * @version $Id$
 */

require_once(t3lib_extMgm::extPath('auxo') . 'core/class.tx_auxo_loader.php');

/**	
 * Test Case for Class Inspector
 *	
 * @package auxo
 * @subpackage tests
 * @version $Id$	
 * @copyright Copyright belongs to the respective authors
 * @author AHN
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License, version 2
 */

interface tx_auxo_FixtureInspectionInterface {
	public function Z();
}

abstract class tx_auxo_FixtureAbstractInspectionClass {
	abstract public function D();
}

class tx_auxo_FixtureInspectionClass implements tx_auxo_FixtureInspectionInterface {
	public static $stringA = 'TestA';	
	
	public static $intB = 123;
	
	public function __construct($argument='') {		
	}
	
	public function A() { 		
	}
	
	public function B() { 	
	}
	
	public function X($option) {		
	}
	
	public function Y(tx_auxo_Cache $cache) {		
	}
	
	public function Z() {		
	}
}

class tx_auxo_ClassInspector_testcase extends PHPUnit_Framework_testcase  {
	
	private $loader = NULL;
	private $inspector = NULL;
	
	/**
	 * Sets up a test enviroment of this testcase.
	 */
	public function setUp() {
		$this->loader = new tx_auxo_loader();
		$this->inspector = new tx_auxo_ClassInspector();
	}
	
	/**
	 * Testcase for class inspector instance
	 * 
	 * @return void
	 */
	public function testAvailable() {
		$this->assertTrue($this->inspector instanceof tx_auxo_ClassInspector);
	}

	/**
	 * Testcase for hasMethod 
	 * 
	 * @return void
	 */	
	public function testHasMethod() {
		$this->assertTrue($this->inspector->hasMethod('tx_auxo_FixtureInspectionClass', 'A'));
		$this->assertTrue($this->inspector->hasMethod('tx_auxo_FixtureInspectionClass', 'B'));
		$this->assertTrue($this->inspector->hasMethod('tx_auxo_FixtureInspectionClass', 'Z'));		
		$this->assertFalse($this->inspector->hasMethod('tx_auxo_FixtureInspectionClass', 'C'));
	}

	/**
	 * Testcase for getReflection
	 * 
	 * @return void
	 */	
	public function testGetReflection() {
		$this->assertTrue($this->inspector->getReflection('tx_auxo_FixtureInspectionClass') instanceof tx_auxo_arrayObject);
		$this->assertEquals(count($this->inspector->getReflection('tx_auxo_FixtureInspectionClass')), 3);
		$this->assertTrue($this->inspector->getReflection('tx_auxo_FixtureInspectionClass')->has('class'));
		$this->assertTrue($this->inspector->getReflection('tx_auxo_FixtureInspectionClass')->has('methods'));
		$this->assertTrue($this->inspector->getReflection('tx_auxo_FixtureInspectionClass')->has('properties'));		
		$this->assertEquals($this->inspector->getReflection('tx_auxo_FixtureInspectionClass')->class->getName(), 'tx_auxo_FixtureInspectionClass');		
	}

	/**
	 * Testcase for getProperty
	 * 
	 * @return void
	 */	
	public function testGetProperty() {
		$this->assertEquals($this->inspector->getProperty('tx_auxo_FixtureInspectionClass', 'stringA'), 'TestA');
		$this->assertEquals($this->inspector->getProperty('tx_auxo_FixtureInspectionClass', 'intB'), 123);		
	}

	/**
	 * Testcase for newInstance
	 * 
	 * @return void
	 */	
	public function testNewInstance() {
		$this->assertTrue($this->inspector->newInstance('tx_auxo_FixtureInspectionClass') instanceof tx_auxo_FixtureInspectionClass);
	}

	/**
	 * Testcase for newInstance with passing arguments
	 * 
	 * @return void
	 */	
	public function testNewInstanceWithArguments() {
		$this->assertTrue($this->inspector->newInstance('tx_auxo_FixtureInspectionClass', array('argument' => 'test')) instanceof tx_auxo_FixtureInspectionClass);
	}	

	/**
	 * Testcase for getMethodParameters
	 * 
	 * @return void
	 */	
	public function testGetMethodParameters() {
		$this->assertTrue(is_array($this->inspector->getMethodParameters('tx_auxo_FixtureInspectionClass', 'X')));
		$this->assertEquals(count($this->inspector->getMethodParameters('tx_auxo_FixtureInspectionClass', 'X')), 1);		
		$parameters = $this->inspector->getMethodParameters('tx_auxo_FixtureInspectionClass', 'X');
		$this->assertEquals($parameters[0]->getName(), 'option');				
	}	

	/**
	 * Testcase for getMethodParameters and determine parameter's type
	 * 
	 * @return void
	 */	
	public function testGetMethodParameterType() {
		$parameters = $this->inspector->getMethodParameters('tx_auxo_FixtureInspectionClass', 'Y');
		$this->assertEquals($parameters[0]->getClass()->getName(), 'tx_auxo_Cache');				
	}	
	
	/**
	 * Testcase for get interfaces implemented by a class 
	 *
	 * @return void
	 */
	public function testGetInterfacesOfAclass() {
		$interfaces = $this->inspector->getInterfaces('tx_auxo_FixtureInspectionClass');
		$this->assertEquals(count($interfaces), 1);
		$this->assertContains('tx_auxo_FixtureInspectionInterface', $interfaces);
	}
	
	/**
	 * Testcase checks if a class is instantiable
	 *
	 * @return void
	 */
	public function testClassIsInstantiable() {
		$this->assertTrue($this->inspector->isInstantiable('tx_auxo_FixtureInspectionClass'));
		$this->assertFalse($this->inspector->isInstantiable('tx_auxo_FixtureAbstractInspectionClass'));
	}
	
	/**
	 * Tears down a created test enviroment of this testcase.
	 */
	public function tearDown() {
		unset($this->inspector);
	}
}